package com.dtx.state;

/**
 * DayState类表示白天的状态。该类实现了State接口,因此它还实现了State接口中声明的所有方法。
 * 对于每个表示状态的类,我们都只会生成一个实例。因为如果每次发生状态改变时都生成一个实例的话,太浪费内存和时间了。
 * 为此,此处我们使用了Singleton模式。
 * doClock是用于设置时间的方法。如果接收到的参数表示晚上的时间,就会切换到夜间状态,即发生状态变化(状态迁移)。
 * 在该类中,我们调用Context接口的changeState方法改变状态。表示晚上状态的类是NightState类,可以通过NightState类的
 * getInstance方法获取它的实例(这里使用了Singleton模式。请注意我们并没有通过new NightState()来生成NightState类的实例。)。
 * doUse,doAlarm,adPhone分别是使用金库,按下警铃,正常通话等事件对应的方法。它们的内部实现都是调用Context中的对应方法。
 * 请注意,在这些方法中,并没有任何"判断当前状态"的if语句。在编写这些方法时,开发人员都知道"现在是白天的状态"。在State模式中,
 * 每个状态都用相应的类来表示,因此无需使用if语句或是switch语句来判断状态。
 */
public class DayState implements State{

    private static DayState singleton = new DayState();

    // 构造函数的可见性是private
    private DayState() {
    }

    /**
     * 获取唯一实例
     * @return
     */
    public static State getInstance(){
        return singleton;
    }

    /**
     * 设置时间
     * @param context
     * @param hour
     */
    @Override
    public void doClock(Context context, int hour) {
        if(hour < 9 || 17 <= hour){
            context.changeState(NightSate.getInstance());
        }
    }

    /**
     * 使用金库
     * @param context
     */
    @Override
    public void doUse(Context context) {
        context.recordLog("使用金库(白天)");
    }

    /**
     * 按下警铃
     * @param context
     */
    @Override
    public void doAlarm(Context context) {
        context.callSecurityCenter("按下警铃(白天)");
    }

    /**
     * 正常通话
     * @param context
     */
    @Override
    public void adPhone(Context context) {
        context.callSecurityCenter("正常通话(白天)");
    }

    /**
     * 显示表示类的文字
     * @return
     */
    @Override
    public String toString() {
        return "[白天]";
    }
}
